package com.swmsss.android_message_receiver;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpDelete;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpPut;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.util.EntityUtils;

import android.app.Activity;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.provider.ContactsContract;
import android.provider.ContactsContract.PhoneLookup;
import android.telephony.SmsManager;
import android.telephony.SmsMessage;
import android.util.Log;

public class MessageReceiver extends BroadcastReceiver {
	
	private static final String tag = "MessageReceiver";
	
	private Context mContext;
	SharedPreferences pref;
	
	@Override
	public void onReceive(Context context, Intent intent) {
		// TODO Auto-generated method stub
		mContext = context;
		
		//if switch is off, do nothing
        pref = mContext.getSharedPreferences("com.swmsss.android_message_receiver", Activity.MODE_PRIVATE);
        boolean bReceiveMessage = pref.getBoolean("ReceiveMessages", false);
        if(bReceiveMessage == false) return;
		
		Bundle bundle = intent.getExtras();
		SmsMessage[] messages = null;
		
		if(bundle != null) {
			String originating_address, message_body, sender_name, operation_code = null;
			
			Object[] pdus = (Object[])bundle.get("pdus");
			messages = new SmsMessage[pdus.length];
			
			boolean abortBroadcast = true;
			
			for(int i=0; i<messages.length;  i++) {
				messages[i] = SmsMessage.createFromPdu((byte[])pdus[i]);
				
				originating_address = messages[i].getOriginatingAddress();
				message_body = messages[i].getMessageBody().toString();

				Uri lookupUri = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, Uri.encode(originating_address));
				String[] mPhoneNumberProjection = { PhoneLookup._ID, PhoneLookup.NUMBER, PhoneLookup.DISPLAY_NAME };
				Cursor cur = context.getContentResolver().query(lookupUri,mPhoneNumberProjection, null, null, null);
				
				sender_name = originating_address;

				try { 
					if (cur.moveToFirst()) 
						sender_name = cur.getString(cur.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));
				}  finally { 
					if (cur != null) {
						cur.close(); 
					}
				}
				
				if(!message_body.startsWith("#")) {
					abortBroadcast = false;
					continue;
				}
				
				//token message
				String[] tokens = message_body.split("#");
				if(tokens.length > 1) {
					operation_code = tokens[1];
				} else {
					operation_code = null;
				}
				if(tokens.length > 2) {
					message_body = tokens[2];
				} else {
					message_body = null;
				}
				
				//log
				if(messages.length != 1) {
					Log.i(tag, "message["+i+"]");
				}
				Log.i(tag, "originating_address: " + originating_address);
				Log.i(tag, "message_body: " + message_body);
				Log.i(tag, "sender_name: " + sender_name);
				Log.i(tag, "operation_code: " + operation_code);
				
				String result_message = null;
				if(tokens.length >= 1) {
					switch(operation_code.charAt(0)) {
						case 'C':
						case 'c':
							//create
							Log.i(tag, "crate");
							result_message = create(originating_address, sender_name, message_body);
							break;
						case 'R':
						case 'r':
							//retrieve
							Log.i(tag, "retrieve");
							result_message = retrieve(originating_address);
							Log.i(tag, result_message);

							break;
						case 'U':
						case 'u':
							//update
							Log.i(tag, "update");
							result_message = update(originating_address, sender_name, message_body);
							break;
						case 'D':
						case 'd':
							//delete
							Log.i(tag, "delete");
							result_message = delete(originating_address);
							break;
						default:
							//?
					}
				}
				
				try {
					if(operation_code.charAt(1) == 'r' || operation_code.charAt(1) == 'R') {
						//send result message
						Log.i(tag, "send result message");
						
						PendingIntent pi = PendingIntent.getBroadcast(context, 0, new Intent(), 0);                
		    	        		SmsManager sms = SmsManager.getDefault();
		    	        		sms.sendTextMessage(originating_address, null, result_message, pi, null);       
					}
				} catch(Exception e) {
					
				}
			}
			
			if(abortBroadcast) {
				this.abortBroadcast();
			}
		}
	}
	
	
	private static final String url = "http://aptpwlqhem.appspot.com/mymsg";
	
	private static String getURL(String phoneNumber) {
		phoneNumber = convertStringForURL(phoneNumber);
		
		return url + "?phoneNumber=" + phoneNumber;
	}
	private static String getURL(String phoneNumber, String name, String content) {
		phoneNumber = convertStringForURL(phoneNumber);
		name = convertStringForURL(name);
		content = convertStringForURL(content);

		return url + "?phoneNumber=" + phoneNumber + "&name=" + name + "&content=" + content;
	}
	
	private String create(String phoneNumber, String name, String content) {
		try {
	        HttpClient client = new DefaultHttpClient();  
	        HttpPost post = new HttpPost(getURL(phoneNumber, name, content));
	        HttpResponse responsePost = client.execute(post);  
	        HttpEntity resEntityPost = responsePost.getEntity();  
	        if (resEntityPost != null) {  
	        		Log.w(tag, EntityUtils.toString(resEntityPost));
	        }
		} catch (Exception e) {
		    e.printStackTrace();
		}
		
		return "Create Success! Check out the message board:)";
	}
	
	private String retrieve(String phoneNumber) {
		try {
	        HttpClient client = new DefaultHttpClient();  
	        HttpGet get = new HttpGet(getURL(phoneNumber));
	        HttpResponse responseGet = client.execute(get);  
	        HttpEntity resEntityGet = responseGet.getEntity();  
	        if (resEntityGet != null) {  
				return new String(EntityUtils.toByteArray(resEntityGet), "utf-8");

//	        		return new String(EntityUtils.toString(resEntityGet));
	        }
		} catch (Exception e) {
		    e.printStackTrace();
		}
		
		return "Retrieve Failed! Message not found:(";
	}
	
	private String update(String phoneNumber, String name, String content) {
		try {
	        HttpClient client = new DefaultHttpClient();  
	        HttpPut put = new HttpPut(getURL(phoneNumber, name, content));
	        HttpResponse responsePut = client.execute(put);  
	        HttpEntity resEntityPut = responsePut.getEntity();  
	        if (resEntityPut != null) {  
	        		Log.w(tag, EntityUtils.toString(resEntityPut));
	        }
		} catch (Exception e) {
		    e.printStackTrace();
		}
		
		return "Update Success! Check out the message board:)";
	}
	
	private String delete(String phoneNumber) {
		try {
	        HttpClient client = new DefaultHttpClient();  
	        HttpDelete delete = new HttpDelete(getURL(phoneNumber));
	        HttpResponse responseDelete = client.execute(delete);  
	        HttpEntity resEntityDelete = responseDelete.getEntity();  
	        if (resEntityDelete != null) {  
	        		Log.w(tag, EntityUtils.toString(resEntityDelete));
	        }
		} catch (Exception e) {
		    e.printStackTrace();
		}
		
		return "Delete Success! Check out the message board:)";
	}
	
	public static String convertStringForURL(String str) {
		String converted_str;
		
		// ' ' -> %20
		converted_str = str.replaceAll(" ", "%20");
		
		// '\n' -> %20
		converted_str = converted_str.replaceAll("\n", "%20");
		
		// '\r' -> %20
		converted_str = converted_str.replaceAll("\r", "%20");
		
		return converted_str;
	}
}
